package com.neusoft.hifly.core.token.filter;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.validation.MessageCodesResolver;
import org.springframework.validation.Validator;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.config.annotation.AsyncSupportConfigurer;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.neusoft.hifly.core.token.config.JwtConfig;

@EnableWebMvc
@Configuration
public class InterceptorConfiguration implements WebMvcConfigurer {

	@Autowired
	private HttpInterceptor httpInterceptor;

	@Autowired
	private JwtInterceptor jwtInterceptor;

	@Autowired(required = false)
	private JwtConfig jwtConfig;

	@Override
	public void addInterceptors(final InterceptorRegistry registry) {
		// 解决跨域问题
		registry.addInterceptor(httpInterceptor).addPathPatterns("/**");
		if (jwtConfig.isEnable()) {
			// 拦截需要验证Token的接口
			registry.addInterceptor(jwtInterceptor).addPathPatterns(jwtConfig.getAuthorisedUrls())
					// 排除登录和重新获取Token的两个接口
					.excludePathPatterns(jwtConfig.getExcludeUrls());
		}
	}

	/**
	 * 配置swagger的ui页面
	 */
	@Override
	public void addResourceHandlers(final ResourceHandlerRegistry registry) {
		// Knife4j
		registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
		// 解决swagger不显示问题
		registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
		registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
	}

	/**
	 * TOD Spring Boot 解决long、bigint转json丢失精度
	 */
	@Override
	public void configureMessageConverters(final List<HttpMessageConverter<?>> converters) {
		final MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
		//ObjectMapper 是Jackson库的主要类。它提供一些功能将转换成Java对象匹配JSON结构,反之亦然
		final ObjectMapper objectMapper = new ObjectMapper();
		final SimpleModule simpleModule = new SimpleModule();
		//序列化将Long转String类型
		simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
		simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
		final SimpleModule bigIntegerModule = new SimpleModule();
		//序列化将BigInteger转String类型
		bigIntegerModule.addSerializer(BigInteger.class, ToStringSerializer.instance);
		final SimpleModule bigDecimalModule = new SimpleModule();
		//序列化将BigDecimal转String类型
		bigDecimalModule.addSerializer(BigDecimal.class, ToStringSerializer.instance);
		objectMapper.registerModule(simpleModule);
		objectMapper.registerModule(bigDecimalModule);
		objectMapper.registerModule(bigIntegerModule);
		jackson2HttpMessageConverter.setObjectMapper(objectMapper);
		converters.add(jackson2HttpMessageConverter);
	}

	@Override
	public void addArgumentResolvers(final List<HandlerMethodArgumentResolver> arg0) {

	}

	@Override
	public void addCorsMappings(final CorsRegistry arg0) {

	}

	@Override
	public void addFormatters(final FormatterRegistry arg0) {

	}

	@Override
	public void addReturnValueHandlers(final List<HandlerMethodReturnValueHandler> arg0) {

	}

	@Override
	public void addViewControllers(final ViewControllerRegistry arg0) {

	}

	@Override
	public void configureAsyncSupport(final AsyncSupportConfigurer arg0) {

	}

	@Override
	public void configureContentNegotiation(final ContentNegotiationConfigurer arg0) {

	}

	@Override
	public void configureDefaultServletHandling(final DefaultServletHandlerConfigurer arg0) {

	}

	@Override
	public void configureHandlerExceptionResolvers(final List<HandlerExceptionResolver> arg0) {

	}

	@Override
	public void configurePathMatch(final PathMatchConfigurer arg0) {

	}

	@Override
	public void configureViewResolvers(final ViewResolverRegistry arg0) {

	}

	@Override
	public void extendHandlerExceptionResolvers(final List<HandlerExceptionResolver> arg0) {

	}

	@Override
	public void extendMessageConverters(final List<HttpMessageConverter<?>> arg0) {

	}

	@Override
	public MessageCodesResolver getMessageCodesResolver() {

		return null;
	}

	@Override
	public Validator getValidator() {

		return null;
	}
}